/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package parser.part.n3;

/**
 *
 * @author Patronus
 */
class Find extends Ruler {

    Find(int i) {
        super(i);
    }
     Find() {
        super(16);
    }

    @Override
    public Object exequteRule() {
        String s = (String) args[0];
        String f = (String) args[1];
        int i = 0;
        int count = 0;
        while (s.indexOf(f, i) != -1) {
            i = s.indexOf(f, i) + 1;
            count++;
        }
        return count;
    }
}

class Concat extends Ruler {

    Concat(int i) {
        super(i);
    }
     Concat() {
        super(16);
    }

    @Override
    public Object exequteRule() {
        int i = 0;
        String r = "";

        while (i < args.length && args[i] != null) {
            r += (String) args[i];
            i++;
        }
        return r;
    }
}

class Check extends Ruler {

    @Override
    public Object exequteRule() {

        String s = (String) args[0];
        String f = (String) args[1];


        if (s != null || f != null) {
            return true;
        } else {
            return null;
        }
    }

    public Check(int arguments_count) {
        super(arguments_count);
    }
     public Check() {
        super(16);
    }
}

class Summ extends Ruler {

    public Summ(int arguments_count) {
        super(arguments_count);
    }

      public Summ() {
        super(16);
    }
    @Override
    public Object exequteRule() {


        if (args[0] != null && args[1] != null) {
            int ret = (Integer) args[0] + (Integer) args[1];
            return ret;
        }
        return -1;

    }
}

class Not extends Ruler {

    Not(int i) {
        super(i);
    }
     Not() {
        super(16);
    }

    @Override
    public Object exequteRule() {
        for (Object t : this.args) {
            if (t != null) {
                return false;
            }
        }
        return true;
    }
}

class And extends Ruler {

    And(int i) {
        super(i);
    }
     And() {
        super(16);
    }

    @Override
    public Object exequteRule() {
        for (Object t : this.args) {
            if (t == null) {
                return false;
            }
        }
        return true;
    }
}

class Or extends Ruler {

    Or(int i) {
        super(i);
    }

    @Override
    public Object exequteRule() {
        for (Object t : this.args) {
            if (t != null) {
                return true;
            }
        }
        return false;
    }
}

class KMP extends Ruler {

    KMP(int i) {
        super(i);
    }

    @Override
    public Object exequteRule() {
        return kmp((String) this.args[0], (String) this.args[1]);
    }
    private int counter = 1;
    private int i = 0;
    private int[] prefixFunc;

    int[] getPrefixFunc(String pattern) {
        prefixFunc = new int[pattern.length()];
        char[] str = pattern.toCharArray();


        for (char ex : str) {

            if (ex == str[counter]) {
                counter++;
                prefixFunc[i] = counter;
            } else {
                counter = 0;
                prefixFunc[i] = 0;
            }
            i++;
        }

        return prefixFunc;
    }

    int kmp(String text, String pattern) {
        int prefix[] = getPrefixFunc(pattern);

        char[] t = text.toCharArray();
        char[] p = pattern.toCharArray();
        int n = text.length();
        int j = 0;
        int m = pattern.length();
        for (int k = 0; k < n; k++) {
            while (true) {
                if (t[k] == p[j]) {
                    j++;
                    if (j == m) {
                        int ret = k - m;
//                        System.out.print("Position :" + (k - m));
//                        System.out.println(";String :" + text.substring(k - m + 1));


                        j = prefix[0];
                        return ret + 2;
                    }
                    break;
                } else if (j == 0) {
                    break;
                } else {
                    j = prefix[j];
                }
            }

        }

        return -1;
    }
}
